package com.ruoyi.cbs.approval.services;

import com.ruoyi.cbs.approval.config.ApprovalConstant;
import com.ruoyi.cbs.approval.domain.ApprovalConfig;
import com.ruoyi.cbs.approval.domain.ApprovalResult;
import com.ruoyi.cbs.approval.domain.ApprovalUser;
import com.ruoyi.cbs.approval.domain.vo.ApprovalReqVO;
import com.ruoyi.cbs.approval.domain.vo.ApprovalResultVO;
import com.ruoyi.cbs.approval.domain.vo.StartInstanceReqVO;
import com.ruoyi.cbs.approval.service.IApprovalConfigService;
import com.ruoyi.cbs.approval.service.IApprovalResultService;
import com.ruoyi.cbs.approval.service.IApprovalUserService;
import com.ruoyi.cbs.contract.services.ContractorServices;
import com.ruoyi.common.enums.project.ApprovalExcuteStatusEnum;
import com.ruoyi.common.enums.project.ApprovalStatusEnum;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ApprovalServices {
    @Autowired
    private ContractorServices contractorServices;
    @Autowired
    private IApprovalUserService approvalUserService;
    @Autowired
    private IApprovalConfigService approvalConfigService;
    @Autowired
    private IApprovalResultService approvalResultService;



    /**
     * 创建审批工作任务
     * @param startInstanceReqVO
     * @return
     */
    public int startApprovalInstance(StartInstanceReqVO startInstanceReqVO) {
        // 审核对象类型：承包商 项目
        String targetType = startInstanceReqVO.getTargetType();
        // 审批类型:  1准入审核  2开工审核
        String approvalType = startInstanceReqVO.getApprovalType();
        // 查询所有审批人
        List<ApprovalUser> approvalUserList = approvalUserService.selectByApprovalType(approvalType);
        if (CollectionUtils.isEmpty(approvalUserList)) {
            return 0;
        }

        // 遍历并给审核人添加审核任务
        int approvalCount = 0;
        ApprovalUser approvalUser = null;
        ApprovalResult approvalResult = null;
        for (int i=0; i < approvalUserList.size(); i++) {
            approvalResult = new ApprovalResult();
            approvalUser = approvalUserList.get(i);

            // 设置审批流状态
            int firstStep = i==0 ? approvalUser.getSeqNum() : 1;
            approvalResult.setExecuteStatus((firstStep == approvalUser.getSeqNum())
                    ? ApprovalExcuteStatusEnum.WORKING.getCode()
                    : ApprovalExcuteStatusEnum.UNSTART.getCode());

            approvalResult.setTargetName(startInstanceReqVO.getTargetName());
            approvalResult.setTargetId(startInstanceReqVO.getTargetId());
            approvalResult.setTargetType(targetType);
            approvalResult.setApprovalType(approvalType);
            approvalResult.setConfigId(approvalUser.getConfigId());
            approvalResult.setApprovalStep(approvalUser.getApprovalStep());
            approvalResult.setApprovalUserId(approvalUser.getUserId());
            approvalResult.setApprovalUserName(approvalUser.getUserName());
            approvalResult.setApprovalStatus(ApprovalStatusEnum.WAITING.getCode());
            approvalResult.setRequireSign(startInstanceReqVO.getRequireSign());
            approvalResultService.insertApprovalResult(approvalResult);

            approvalCount++;
        }

        return approvalCount;
    }

    /**
     * 查询用户的审批任务
     * @return
     */
    public List<ApprovalResultVO> selectUserApprovalList(String targetName, String approvalType, String status) {
        ApprovalResult searchEntity = new ApprovalResult();
        searchEntity.setExecuteStatus(status);
        searchEntity.setTargetName(targetName);
        searchEntity.setApprovalType(approvalType);

        // 查询用户审批任务
        List<ApprovalResult> approvalResultList = approvalResultService.selectUserApprovalList(searchEntity);
        List<ApprovalResultVO> resultVOList = new ArrayList<>();
        for (ApprovalResult approvalResult : approvalResultList) {
            ApprovalResultVO approvalResultVO = new ApprovalResultVO();
            BeanUtils.copyProperties(approvalResult, approvalResultVO);
            approvalResultVO.setApprovalId(approvalResult.getId());
            resultVOList.add(approvalResultVO);
        }
        return resultVOList;
    }

    /**
     * 获取审批详情
     * @param targetId
     * @param targetType
     * @return
     */
    public List<ApprovalResultVO> getApprovalDetail(String targetId, String targetType) {
        // 查询审批结果
        ApprovalResult approvalResult = new ApprovalResult();
        List<ApprovalResultVO> resultVOList = new ArrayList<>();
//        approvalResult.setTargetId(targetId);
//        approvalResult.setTargetType(targetType);
//        List<ApprovalResult> approvalResultList = approvalResultService.getUserWorkingApprovalList(approvalResult);
//        for (ApprovalResult approvalResult : approvalResultList) {
//            ApprovalResultVO approvalResultVO = new ApprovalResultVO();
//            BeanUtils.copyProperties(approvalResult, approvalResultVO);
//            approvalResultVO.setApprovalId(approvalResult.getId());
//            resultVOList.add(approvalResultVO);
//        }
        return resultVOList;
    }


    /**
     * 保存 审批结果
     * @param approvalReqVO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)  // 添加事务管理
    public int approval(ApprovalReqVO approvalReqVO) {
        // 参数验证
        validateApprovalParams(approvalReqVO);

        // 获取当前审批流程
        ApprovalResult approvalResult = getApprovalResult(approvalReqVO);

        // 检查签字要求
        checkSignRequirement(approvalReqVO, approvalResult);

        // 更新审批结果
        updateApprovalResult(approvalReqVO, approvalResult);

        // 处理审批通过逻辑
        if (ApprovalStatusEnum.APPROVED.getCode().equals(approvalReqVO.getApprovalStatus())) {
            handleApprovalPassed(approvalResult);
            processNextApprovalStep(approvalResult);
        }

        // 处理审批不通过逻辑
        if (ApprovalStatusEnum.REJECTED.getCode().equals(approvalReqVO.getApprovalStatus())) {
            handleApprovalRejected(approvalResult);
        }

        // 更新审批对象状态
        if (ApprovalConstant.TARGET_TYPE_CONTRACTOR.equals(approvalResult.getTargetType())) {
            // 承包商
            contractorServices.saveAdmitApprovalResult(approvalResult.getTargetId(), approvalReqVO.getApprovalStatus());
        } else if (ApprovalConstant.TARGET_TYPE_PROJECT.equals(approvalResult.getTargetType())) {
            // 项目
            // ????????????????????????????????????
        }

        return 1;
    }

    // 新增辅助方法：参数验证
    private void validateApprovalParams(ApprovalReqVO approvalReqVO) {
        if (approvalReqVO == null || approvalReqVO.getApprovalId() == null
                || StringUtils.isEmpty(approvalReqVO.getApprovalStatus())) {
            throw new IllegalArgumentException("审批参数错误！");
        }
    }

    // 新增辅助方法：获取审批结果
    private ApprovalResult getApprovalResult(ApprovalReqVO approvalReqVO) {
        ApprovalResult approvalResult = approvalResultService.selectApprovalResultById(approvalReqVO.getApprovalId());
        if (approvalResult == null) {
            throw new ServiceException("审批数据异常！");
        }
        return approvalResult;
    }

    // 新增辅助方法：检查签字要求
    private void checkSignRequirement(ApprovalReqVO approvalReqVO, ApprovalResult approvalResult) {
        if (ApprovalStatusEnum.APPROVED.getCode().equals(approvalReqVO.getApprovalStatus())
                && "1".equals(approvalResult.getRequireSign())
                && StringUtils.isEmpty(approvalReqVO.getSignUrl())) {
            throw new IllegalArgumentException("审批结果要求必须签字！");
        }
    }

    // 新增辅助方法：更新审批结果
    private void updateApprovalResult(ApprovalReqVO approvalReqVO, ApprovalResult approvalResult) {
        ApprovalResult updateEntity = new ApprovalResult();
        updateEntity.setId(approvalResult.getId());
        updateEntity.setApprovalStatus(approvalReqVO.getApprovalStatus());
        updateEntity.setComment(approvalReqVO.getComment());
        updateEntity.setApprovalTime(DateUtils.getNowDate());
        updateEntity.setSignUrl(approvalReqVO.getSignUrl());
        updateEntity.setExecuteStatus(ApprovalExcuteStatusEnum.COMPLETE.getCode());
//        updateEntity.setIfOperate("1");

        int rs = approvalResultService.updateApprovalResult(updateEntity);
        if (rs <= 0) {
            throw new IllegalArgumentException("审批结果更新失败！");
        }
    }

    // 新增辅助方法：处理审批通过
    private void handleApprovalPassed(ApprovalResult approvalResult) {
        // 删除同节点下其它人的审核任务
        approvalResultService.deleteByConfigId(
                approvalResult.getConfigId(),
                approvalResult.getTargetId(),
                approvalResult.getTargetType()
        );
    }

    // 新增辅助方法：处理审批不通过
    private int handleApprovalRejected(ApprovalResult approvalResult) {
        // 删除该对象上未执行的审核节点
        approvalResultService.deleteByTargetId(approvalResult.getTargetId(), approvalResult.getTargetType());
        return 1;
    }

    // 新增辅助方法：处理下一个审批步骤
    private int processNextApprovalStep(ApprovalResult approvalResult) {
        ApprovalConfig approvalConfig = approvalConfigService.selectApprovalConfigById(approvalResult.getConfigId());
        if (approvalConfig == null) {
            throw new IllegalArgumentException("审批节点不存在！");
        }

        // 查询下一个审批节点
        List<ApprovalConfig> nextStepList = approvalConfigService.selectNextByTypeAndSeqNum(
                approvalConfig.getApprovalType(),
                approvalConfig.getSeqNum()
        );

        if (CollectionUtils.isNotEmpty(nextStepList)) {
            ApprovalResult updateEntity2 = new ApprovalResult();
            updateEntity2.setTargetId(approvalResult.getTargetId());
            updateEntity2.setTargetType(approvalResult.getTargetType());
            updateEntity2.setExecuteStatus(ApprovalExcuteStatusEnum.WORKING.getCode());

            for (ApprovalConfig nextStep : nextStepList) {
                updateEntity2.setConfigId(nextStep.getId());
                approvalResultService.updateExecuteStatus(updateEntity2);
            }
            return 1;
        }

        return 1;
    }



}
